package com.encyclopedia.utils;

import com.alibaba.fastjson2.JSON;
import com.encyclopedia.result.JsonRequest;
import com.encyclopedia.result.exenum.RequestException;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * JSON序列化工具类,解决部分反序列化问题
 *
 * @author by 春风能解释
 * <p>
 * 2023/11/30
 */
public class JsonSerializeUtils {

    /**
     * 反序列化
     *
     * @param json   JSON字符串
     * @param tClass 待转换的类型
     * @param <T>    类型
     * @return 指定类型的对象
     */
    public static <T> T deserialize(String json, Class<T> tClass) {
        return JSON.parseObject(json, tClass);
    }

    /**
     * 序列化对象
     *
     * @param obj 对象
     * @return JSON
     */
    public static String serialize(Object obj) {
        return JSON.toJSONString(obj);
    }

    /**
     * 将Object对象转换为指定类型
     *
     * @param <T> 类型
     * @return 指定类型的对象
     */
    public static <T> T reSerialize(Object obj, Class<T> tClass) {
        //首先序列化
        String serialize = serialize(obj);
        //再反序列化
        return deserialize(serialize, tClass);
    }

    /**
     * 将对象序列化为数组
     *
     * @param obj    对象
     * @param tClass 指定类型
     * @param <T>    类型
     * @return 指定类型的对象
     */
    public static <T> List<T> serializeList(Object obj, Class<T> tClass) {
        //首先序列化
        String serialize = serialize(obj);
        //再反序列化
        return JSON.parseArray(serialize, tClass);
    }

    /**
     * HTTP响应打印工具
     *
     * @param exception 异常对象
     * @param response  响应体
     */
    public static void responseWriter(RequestException exception, HttpServletResponse response) throws IOException {
        //设置字符编码
        response.setContentType("application/json;charset=UTF-8");
        //响应体打印
        response
                .getWriter()
                .println(
                        JsonSerializeUtils
                                .serialize(JsonRequest.error(exception)
                                ));
    }

    /**
     * 对象转Map集合
     *
     * @param object 对象
     * @return Map集合
     */
    public Map<String, Object> objectConversionMap(Object object) {
        try {
            //获取字节码对象
            Class<?> aClass = object.getClass();
            //获取字段集合
            Field[] fields = aClass.getFields();
            Map<String, Object> map = new HashMap<>();
            for (Field field : fields) {
                Object value = field.get(aClass);
                //值为空,不填充
                if (Objects.isNull(value)) {
                    continue;
                }
                field.setAccessible(true);//暴力破解
                map.put(field.getName(), value);
            }
            return map;
        } catch (Exception e) {
            return null;
        }
    }

}
